home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / jove4.9 / part08 < prev    next >
Encoding:
Internet Message Format  |  1988-04-25  |  52.2 KB

  1. Subject:  v14i064:  Jove, an emacs variant, version 4.9, Part08/21
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
  7. Posting-number: Volume 14, Issue 64
  8. Archive-name: jove4.9/part08
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 8 (of 21)."
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f './Readme.mac' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'./Readme.mac'\"
  22. else
  23. echo shar: Extracting \"'./Readme.mac'\" \(17320 characters\)
  24. sed "s/^X//" >'./Readme.mac' <<'END_OF_FILE'
  25. X/***************************************************************************
  26. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  27. X * is provided to you without charge, and with no warranty.  You may give  *
  28. X * away copies of JOVE, including sources, provided that this notice is    *
  29. X * included in all the files.                                              *
  30. X ***************************************************************************/
  31. X
  32. Introduction
  33. X
  34. This file contains a brief description of MacJove, along with
  35. information necessary to make MacJove from the source files.
  36. It is assumed that the reader is familiar with Jove from other
  37. systems, and is somewhat familiar with the Macintosh as well. In
  38. the future there may be a separate user's manual for MacJove: 
  39. for the time being, the reader should refer to the Jove manual
  40. for Unix users.
  41. X
  42. Description
  43. X
  44. MacJove is a direct port of Jove to the Macintosh, with the
  45. overall structure, commands and key bindings left intact. In
  46. addition, elements of the Macintosh user interface - menus,
  47. window controls, and the mouse, have been integrated in a manner
  48. consistent with the overall functioning of Jove.
  49. X
  50. While the integration of these tools into the Jove environment
  51. is consistent and, to most users, familiar, Jove departs in
  52. several places from "Macintosh User Interface Guidelines". Most
  53. notably, the mouse is used to position the point only, not to
  54. drag or select text, and the Jove buffer structure is not
  55. integrated with the clipboard. Also, key bindings conform to
  56. Jove/Emacs tradition, and not to Macintosh guidelines: i.e.
  57. control (command)-N is next-line, not "NewFile". The reason for
  58. these departures is that the majority of MacJove users are likely
  59. to be those already familiar with Jove or other Emacs editors
  60. on other systems, and for these users, consistency between machines
  61. and operating systems is more important than fully exploiting
  62. the features of a single system. There are numerous other text
  63. editors which fully follow the Macintosh User Interface Guidelines.
  64. X
  65. MacJove retains most features of other Joves, but certain commands
  66. cannot be implemented because of the Macintosh operating system.
  67. Thus, there is no way to run a sub-process or a shell in a window,
  68. because there are no shells to run on the Macintosh, and a program
  69. X(currently) can only transfer control to another program, not run
  70. a child process. For similar reasons, commands dealing with mail,
  71. with running make, and checking errors, are omitted.
  72. X
  73. X
  74. X
  75. X                      Running MacJove
  76. X
  77. System Requirements
  78. X
  79. MacJove should run without difficulty on any Macintosh Plus, SE, or
  80. Macintosh II, providing that the hierarchical file system (HFS) is used, and
  81. assuming a reasonably current system file is used. An upgraded 512K Mac
  82. X(with 128K rom) should also work if there is enough memory.  MacJove was
  83. developed on a Macintosh Plus and Macintosh II running system 4.2 and Finder
  84. X6.0., and has not been fully tested on earlier systems - however, it is
  85. likely that it will run on system 3.2 and later versions. MacJove has been
  86. used to a limited extent with Switcher and under Multifinder. In both cases,
  87. it is important to reserve enough memory for MacJove, as discussed below.
  88. X
  89. MacJove, as compiled from the sources, uses memory as follows:
  90. X
  91. X   Program Code     approx 116K
  92. X   Static Data      approx  20K
  93. X   Tempfile Cache           64K (heap)
  94. X                           ____
  95. X                           200K total before stack/heap considerations
  96. X
  97. To this must be added stack and heap space. A bare minimum for this is
  98. probably 100K or so, but the usage will vary as buffers are created.  With
  99. Jove, the file itself takes up space only in the tempfile and its cache, but
  100. the buffer structure requires 3 pointers (12 bytes) for each line in the
  101. file. For a reasonable editing session with files totalling, say 10000 to
  102. X20000 lines, this additional space can add up. For this reason, it is
  103. unrealistic to expect to run Jove on a 512K system, unless a very small
  104. system file is used, few, small files are edited each session, and the
  105. tempfile cache is reduced (see cache size under Making Jove). You can
  106. experiment with various memory allocations under Switcher and Multifinder to
  107. see what works with your editing habits (backup your files first!), but a
  108. realistic minimum is 400K - 500K and more is great.
  109. X
  110. When first using MacJove, and if memory space is questionable, SAVE YOUR
  111. FILES FREQUENTLY. If it is necessary to edit many files, it is often better
  112. to exit MacJove and restart once in a while, especially if there is a
  113. question of limited memory.
  114. X
  115. Operation
  116. X
  117. X
  118. Running MacJove is similar to other Macintosh applications, and should be
  119. intuitive. You start up MacJove by either opening, or double-clicking,
  120. the MacJove icon. If you have previously saved files created with MacJove,
  121. double-clicking on them will also start up the program, and the files will
  122. be put into buffers. Several files can be selected simultaneously by this
  123. method. There is no current way to select command-line options with
  124. MacJove, but this may change in the future.
  125. X
  126. The .joverc file, if used, must be present in the same directory as MacJove,
  127. the "home" directory. The help file, "cmds.doc", must also be in this
  128. directory. The tempfile, ".joveXXX", will be placed in whatever directory is
  129. current when the tempfile is first opened - this may or may not be the home
  130. directory, and may change in the future. The recover file, ".jrecXXX" is
  131. placed in the home directory. While this file is created and updated as on
  132. Unix versions of Jove, there is currently no "recover" program for MacJove.
  133. Hopefully, this will be available soon.
  134. X
  135. MacJove can edit any text file on the Macintosh, whether created with
  136. MacJove or another editor. It cannot be used to edit graphics material, and
  137. graphics material cannot be inserted during operation of MacJove. Files
  138. created with MacJove are of type 'TEXT' and of signature 'JV01'. This
  139. signature is being registered with Apple, and may change if necessary. Note
  140. that once MacJove files have been re-edited with another editor, they likely
  141. will have new signatures, and double-clicking on them will start the other
  142. editor, not MacJove.
  143. X
  144. The standard Macintosh keyboard is inadequate for MacJove (and most anything
  145. else), so that it is necessary to change a couple of keys. The "`" key
  146. becomes the ESCAPE key, since it is in the right place for one: to send a
  147. real "'", hold the command key down while typing it. The command key is used
  148. for a control key - unfortunately, the location of it is horrible for such a
  149. purpose. On Macintosh SE and Macintosh II models, a real escape key exists,
  150. and also a real control key. Note, however, that because of a small bug in
  151. the keyboard encoding in MacJove, you cannot directly send a NUL (control-@)
  152. with the control key. Typing command-@ or command-2 will still do this,
  153. however.
  154. X
  155. During operation, you can use the keyboard as you would when running Jove on
  156. any other system. However, many commands also have menu equivalents:  as
  157. long as MacJove is waiting for a command, you can use either the keyboard or
  158. the menus. Once you begin selecting a command with either the menus or the
  159. keyboard, the other is locked out: thus, once you type control-X, MacJove
  160. expects more characters, and will not let you choose menu items.  Also, if
  161. you are prompted for input on the command line, the menus are locked out.
  162. Regardless of how a command is begun, however, only the prompt line (message
  163. line) is used for input: MacJove does not use dialog boxes, except under the
  164. X"About Jove" menu selection.
  165. X
  166. Commands listed in the menus are given exactly as their string name in
  167. the command list, for example "write-file". In addition, variables are
  168. listed under the "Set" menu. Variables are grouped by type. Non-boolean
  169. variables are changed on the message line after being selected. Boolean
  170. variables are marked with a check mark if on, and selecting them toggles
  171. the value of the variable.
  172. X
  173. The "Buffer" menu is a special menu, whose action is different than the
  174. others. The first entries on this menu are the major and minor modes of
  175. operation, with those of the current buffer marked with check marks.
  176. Clicking on a major mode will change the major mode of the current buffer to
  177. that mode, while clicking on a minor mode will toggle that mode's status
  178. X(on/off) for the current buffer. Beneath this is a list of buffers, one for
  179. each menu item, with the current buffer marked. Clicking on a buffer selects
  180. that as the current buffer, and the active window will change accordingly.
  181. X
  182. Window controls (scroll bars) work as expected, and are simply bound to
  183. the appropriate MacJove command. Occassionally the position of the
  184. scroll bar may appear inaccurate, particularly with a small buffer.
  185. X
  186. Files and directories may be selected in two ways. The default method
  187. is to use the message line to input filenames, and to change directories
  188. using "cd". If the variable "macify" is set, however, filenames and
  189. directories can also be set using the standard file dialogs familiar to
  190. most Mac users. Filename paths are normally given via Unix conventions,
  191. and not Macintosh conventions: i.e. directories are separated with "/"
  192. and not ":". On the Buffer menu, however, filenames are listed with ":"
  193. as the separation character, since "/" cannot be displayed in menu items.
  194. It is not possible to back up directories beyond the volume level, so
  195. there is not true "root". To change volumes (disks), macify must be on,
  196. and the "Drive" selection used.
  197. X
  198. X"Macify" only works for those commands which REQUIRE a file operation, such
  199. as "visit-file", "insert-file", "write-file".  Operations which first look
  200. in buffers for files, such as "window-find" and "find-file" never use the
  201. standard file dialogs.
  202. X
  203. For a list of all commands and bindings, click on "About Jove" in the
  204. Apple menu. In the future this may also support the help file.
  205. X
  206. X                      Making MacJove
  207. X
  208. System Requirements
  209. X
  210. To make MacJove from the sources, you need a hard disk based Macintosh, at
  211. least 1 mb of ram, and the LightspeedC compiler, version 2.13 or later.
  212. Earlier versions may work but have not been used recently. Allow for the
  213. MacJove files to take up to 1.5 mb of your hard disk. You will need a copy
  214. of the "BinHex" utility, also.
  215. X
  216. Since LightspeedC does not work with a Makefile, none is supplied. In
  217. general, the compiler itself will figure out dependencies for you, within a
  218. X"project". Since there are three separate projects to MacJove, you will
  219. still have to keep track of some changes, particularly for the setmaps
  220. project. Also, since LightspeedC only knows of .c and .h dependencies,
  221. you will have to keep track of setmaps.txt and menumaps.txt yourself.
  222. X
  223. Preliminary Steps
  224. X
  225. X0) CREATE A FOLDER (DIRECTORY) FOR JOVE. If I have to tell you how to do
  226. that, don't go any further! Copy the source files - a few aren't needed
  227. by MacJove, but copy them anyway, so you'll have them in one place. You
  228. do not need anything in the "doc" subdirectory to create MacJove (but
  229. you will eventually need cmds.doc, the help file, if you want the
  230. X"describe-command" command to work).
  231. X
  232. X1) CREATE THE RESOURCE FILE: There is only one eight-bit file supplied,
  233. X"mjove.rsrc". This is a small file which contains the program icon and a
  234. dialog template. This file must have the same name as the MacJove project,
  235. plus extension ".rsrc". The MacJove project (below), has name "mjove", so
  236. this file is "mjove.rsrc".  IF YOU RENAME THE PROJECT YOU MUST RENAME THIS
  237. FILE, ALSO. Using "BinHex", unload the file "mjovers.Hqx" --> "mjove.rsrc".
  238. X
  239. X2) CREATE THE "MJOVELIB" PROJECT: MacJove does not use many of the library
  240. functions. Despite what the LightspeedC manual states, projects are loaded
  241. as a whole: since we need only a few functions, we will build a "library" of
  242. them in the form of a project. Run LightspeedC and create a new project,
  243. and name it "mjovelib". Add the following files, from the Library Sources,
  244. to the project. They all go in the same segment:
  245. X
  246. X     onexit.c
  247. X     qsort.c
  248. X     stddata_ctype.c
  249. X     unixexit.c
  250. X     unixid.c
  251. X     unixmem.c
  252. X     unixtime.c
  253. X
  254. X3) EXAMINE THE FILE UNIXTIME.C and make the following correction, if
  255. necessary. The LightspeedC library function "unixtime.c" returns a string
  256. containing the time for what is supposed to be Greenwich Mean Time, instead
  257. of local time. Using the LightspeedC editor, and with the project open,
  258. examine the file, comment out the definition of "GMTzonedif", and add:
  259. X
  260. X     #define GMTzonedif 0
  261. X
  262. X4) MAKE THE "MJOVELIB" PROJECT. Keeping the edited "unixtime.c" open,
  263. run "make" on the project - everything will be compiled, with the altered
  264. version of "unixtime.c". You do not have to permanently save the change
  265. to unixtime.c, but if you do not, the next time you run "make" on the
  266. project, it will tell you that it needs recompiling - simply ignore it.
  267. After the mjovelib project is made, close it. You do not have to convert it
  268. to a library - it is okay to leave it as a project.
  269. X
  270. X6) CREATE THE "MSETMAPS" PROJECT. Create a new project, name it "msetmaps",
  271. and add the following files to it:
  272. X
  273. X     setmaps.c
  274. X     stdio
  275. X     strings           (segment 1)
  276. X     unix
  277. X     unix main.c
  278. X     --------
  279. X     MacTraps          (segment 2)
  280. X
  281. X7) EDIT THE FILE "TUNE.H". The only thing you should have to do with this
  282. file is to make certain that MAC is defined. Uncomment the following line,
  283. near the beginning of the file
  284. X
  285. Change:
  286. X
  287. X  /*#define MAC 1                /* alas, there is no command line for this */
  288. X
  289. to:
  290. X
  291. X  #define MAC 1            /* alas, there is no command line for this */
  292. X
  293. You should not change anything else at this point - unless you want to
  294. reduce memory requirements (see "Running MacJove", above). If it is
  295. necessary to reduce the memory requirements, then reduce the number of cache
  296. buffers, NBUF, which is defined near the end of the file (each buffer takes
  297. up 1K of space while MacJove is running).
  298. X
  299. X     #ifdef MAC
  300. X     #  undef F_COMPLETION        /* can't do it with spaces in filenames */
  301. X     #  undef CHDIR
  302. X     #  define CHDIR 1
  303. X     #  define rindex strrchr
  304. X     #  define index strchr
  305. X     #  define bzero(s,n) setmem(s,n,0)
  306. X     #  define LINT_ARGS
  307. X     #  define NBUF 64 <----------reduce this if necessary.
  308. X     #  define BUFSIZ 1024
  309. X     #endif
  310. X
  311. X8) MAKE THE "MSETMAPS" PROJECT. Then choose "Build Application",and name it
  312. X"setmaps". 
  313. X
  314. X9) RUN "SETMAPS" ON THE KEYMAPS.TXT FILE. You can either run "setmaps" from
  315. LightspeedC, before closing the project, or as the standalone application.
  316. When prompted for the "Unix command line", enter:
  317. X
  318. X     < keymaps.txt > keymaps.c
  319. X
  320. You will get a few messages from setmaps that it can't find certain
  321. commands. You can ignore these.
  322. X
  323. X10) RUN "SETMAPS" ON THE MENUMAPS.TXT FILE. Just as before, run "setmaps"
  324. and enter the following command line:
  325. X
  326. X     < menumaps.txt > menumaps.c
  327. X
  328. You should not get any messages from setmaps. If the "msetmaps" project is
  329. still open, close it.
  330. X
  331. X11) CREATE THE "MJOVE" PROJECT. Create a new project, name it "MJOVE" and
  332. set the Creator (signature) to 'JV01'. Add the following files in the
  333. following segments:
  334. X
  335. X     abbrev.c
  336. X     argcount.c
  337. X     ask.c
  338. X     buf.c
  339. X     c.c
  340. X     case.c        (segment 1)
  341. X     ctype.c
  342. X     delete.c
  343. X     disp.c
  344. X     extend.c
  345. X     --------
  346. X     fmt.c
  347. X     fp.c
  348. X     funcdefs.c    (segment 2)
  349. X     insert.c
  350. X     io.c
  351. X     jove.c
  352. X     keymaps.c
  353. X     --------
  354. X     mac.c
  355. X     macros.c
  356. X     marks.c
  357. X     menumaps.c    (segment 3)
  358. X     misc.c
  359. X     move.c
  360. X     paragraph.c
  361. X     --------
  362. X     re.c
  363. X     re1.c
  364. X     rec.c
  365. X     screen.c
  366. X     table.c       (segment 4)
  367. X     term.c
  368. X     util.c
  369. X     vars.c
  370. X     version.c
  371. X     wind.c
  372. X     --------
  373. X     MacTraps
  374. X     mjovelib
  375. X     setjmp.Lib    (segment 5)
  376. X     storage
  377. X     strings
  378. X
  379. X12) MAKE THE MJOVE PROJECT. If you experience any errors, it will most
  380. likely be from #include files not being in the default path - see the
  381. LightspeedC manual on setting up your directories. When you are done,
  382. run the program from the compiler to verify that it is okay, then save it as
  383. X"MacJove" using the "Build Application" command.
  384. X
  385. X13) (Optional) CREATE THE HELP FILE, "CMDS.DOC". If you do not have a copy
  386. of "cmds.doc", it must be created using nroff. Assuming you have the Jove
  387. sources on a Unix machine, run "Make doc/cmds.doc" to create this file in
  388. the "doc" subdirectory, then move the file to the Mac. If you obtained the
  389. sources from a non-Unix source, this file may already be supplied. Place the
  390. file in the same directory that MacJove will be in.
  391. X
  392. X                      COMMENTS AND QUESTIONS, BUGS
  393. X
  394. This is the first version of MacJove to receive widespread use, and problems
  395. are anticipated. All comments and suggestions are appreciated. Before asking
  396. for help in making MacJove, make sure you understand the above directions,
  397. have followed them closely, and have a good copy of the sources. I will try
  398. to reply to everyone, but have a busy schedule, and cannot guarantee any
  399. time frame of response. I can promise you, however, that questions received
  400. via the net or mail will be answered more promptly than those from via US
  401. Mail. PLEASE DO NOT SEND ME DISKS!
  402. X
  403. X
  404. X    Ken Mitchum
  405. X    Decision Systems Laboratory
  406. X    University of Pittsburgh
  407. X    1360 Scaife Hall
  408. X    Pittsburgh, Pa. 15261
  409. X
  410. X    (km@cadre.dsl.pittsburgh.edu)
  411. X
  412. END_OF_FILE
  413. if test 17320 -ne `wc -c <'./Readme.mac'`; then
  414.     echo shar: \"'./Readme.mac'\" unpacked with wrong size!
  415. fi
  416. # end of './Readme.mac'
  417. fi
  418. if test -f './jove.h' -a "${1}" != "-c" ; then 
  419.   echo shar: Will not clobber existing file \"'./jove.h'\"
  420. else
  421. echo shar: Extracting \"'./jove.h'\" \(16194 characters\)
  422. sed "s/^X//" >'./jove.h' <<'END_OF_FILE'
  423. X/***************************************************************************
  424. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  425. X * is provided to you without charge, and with no warranty.  You may give  *
  426. X * away copies of JOVE, including sources, provided that this notice is    *
  427. X * included in all the files.                                              *
  428. X ***************************************************************************/
  429. X
  430. X/* jove.h header file to be included by EVERYONE */ 
  431. X
  432. X
  433. X#include <setjmp.h>
  434. X
  435. X#ifndef TUNED
  436. X#   include "tune.h"
  437. X#endif
  438. X
  439. X#ifndef MAC
  440. X#    include <sys/types.h>
  441. X#else
  442. X#    include <types.h>
  443. X#endif
  444. X
  445. X
  446. X#ifdef MSDOS
  447. X#include <string.h>
  448. X#endif
  449. X
  450. X
  451. X#if !(defined(MSDOS) || defined(MAC))
  452. X#define void int
  453. X#endif
  454. X
  455. X#if !(defined(IBMPC) || defined(MAC))
  456. X#    define TERMCAP
  457. X#    define ASCII
  458. X#endif
  459. X
  460. X#ifdef ASCII    /* seven bit characters */
  461. X#    define NCHARS 0200
  462. X#else
  463. X#    define NCHARS 0400
  464. X#endif
  465. X#define CHARMASK (NCHARS -1)
  466. X
  467. X#define private    static
  468. X
  469. X#ifndef BSD4_2
  470. X#   ifdef MENLO_JCL
  471. X#    ifndef EUNICE
  472. X#        define signal    sigset
  473. X#    endif
  474. X#   endif /* MENLO_JCL */
  475. X#endif
  476. X
  477. X#define EOF    -1
  478. X
  479. X#ifdef MSDOS
  480. X#    define NULL    ((char *)0)
  481. X#    define NIL    ((char *)0)
  482. X#else
  483. X#    ifdef MAC
  484. X#        define NULL 0L
  485. X#        define NIL 0L
  486. X#    else
  487. X#        define NULL 0
  488. X#        define NIL 0
  489. X#    endif /* MAC */
  490. X#endif /* MSDOS */
  491. X/* kinds of regular expression compiles */
  492. X#define NORM    0    /* nothing special */
  493. X#define OKAY_RE    1    /* allow regular expressions */
  494. X#define IN_CB    2    /* in curly brace; implies OKAY_RE */
  495. X
  496. X/* return codes for command completion (all < 0 because >= 0 are
  497. X   legitimate offsets into array of strings */
  498. X
  499. X#define AMBIGUOUS    -2    /* matches more than one at this point */
  500. X#define UNIQUE        -3    /* matches only one string */
  501. X#define ORIGINAL    -4    /* matches no strings at all! */
  502. X#define NULLSTRING    -5    /* just hit return without typing anything */
  503. X
  504. X/* values for the `flags' argument to complete */
  505. X#define NOTHING        0    /* opposite of RET_STATE */
  506. X#define RET_STATE    1    /* return state when we hit return */
  507. X#define RCOMMAND    2    /* we are reading a joverc file */
  508. X#define CASEIND        4    /* map all to lower case */
  509. X
  510. X#define SAVE        01    /* this macro needs saving to a file */
  511. X
  512. X#define    LBSIZE        BUFSIZ    /* same as a logical disk block */
  513. X#ifndef MSDOS
  514. X#define FILESIZE    256
  515. X#else /* MSDOS */
  516. X#define FILESIZE    64
  517. X#endif /* MSDOS */
  518. X
  519. X#define FORWARD        1
  520. X#define BACKWARD    -1
  521. X
  522. X#define CTL(c)        (c & 037)
  523. X#define META(c)        (c | 0200)
  524. X#define RUBOUT        '\177'
  525. X#define LF        CTL('J')
  526. X#define CR        CTL('M')
  527. X#define BS        CTL('H')
  528. X#define ESC        '\033'
  529. X
  530. X#define HALF(wp)    ((wp->w_height - 1) / 2)
  531. X#define IsModified(b)    (b->b_modified)
  532. X#define SIZE(wp)    (wp->w_height - 1)
  533. X#define SavLine(a, b)    (a->l_dline = putline(b))
  534. X#define SetLine(line)    DotTo(line, 0)
  535. X#define bobp()        (firstp(curline) && bolp())
  536. X#define bolp()        (curchar == 0)
  537. X#define eobp()        (lastp(curline) && eolp())
  538. X#define eolp()        (linebuf[curchar] == '\0')
  539. X#define firstp(line)    (line == curbuf->b_first)
  540. X#define getDOT()    getline(curline->l_dline, linebuf)
  541. X#define isdirty(line)    (line->l_dline & DIRTY)
  542. X#define lastp(line)    (line == curbuf->b_last)
  543. X#define makedirty(line)    line->l_dline |= DIRTY
  544. X#define one_windp()    (fwind->w_next == fwind)
  545. X
  546. X#define CharUpcase(c)    (CaseEquiv[c])
  547. X
  548. extern int    BufSize;
  549. X
  550. X#define ARG_CMD        1
  551. X#define LINECMD        2
  552. X#define KILLCMD        3    /* so we can merge kills */
  553. X#define YANKCMD        4    /* so we can do ESC Y (yank-pop) */
  554. X
  555. X/* Buffer type */
  556. X
  557. X#define B_SCRATCH    1    /* for internal things, e.g. minibuffer ... */
  558. X#define B_FILE        2    /* normal file (We Auto-save these.) */
  559. X#define B_PROCESS    3    /* process output in this buffer */
  560. X
  561. X/* Major modes */
  562. X#define FUNDAMENTAL    0    /* Fundamental mode */
  563. X#define TEXT        1    /* Text mode */
  564. X#define CMODE        2    /* C mode */
  565. X#ifdef LISP
  566. X#    define LISPMODE        3    /* Lisp mode */
  567. X#    define NMAJORS        4
  568. X#else
  569. X#    define NMAJORS    3
  570. X#endif
  571. X
  572. X/* Minor Modes */
  573. X#define Indent        (1 << 0)    /* indent same as previous line after return */
  574. X#define ShowMatch    (1 << 1)    /* paren flash mode */
  575. X#define Fill        (1 << 2)    /* text fill mode */
  576. X#define OverWrite    (1 << 3)    /* over write mode */
  577. X#define Abbrev        (1 << 4)    /* abbrev mode */
  578. X
  579. X#define BufMinorMode(b, x)    (b->b_minor & x)
  580. X
  581. X#define MinorMode(x)    BufMinorMode(curbuf, x)
  582. X#define MajorMode(x)    (curbuf->b_major == x)
  583. X#define SetMajor(x)    ((curbuf->b_major = x), UpdModLine = YES)
  584. X
  585. X#ifdef ASCII
  586. extern char    CharTable[NMAJORS][128];
  587. extern char    CaseEquiv[128];
  588. X#else /* IBMPC or MAC */
  589. extern char    CharTable[NMAJORS][256];
  590. extern char    CaseEquiv[256];
  591. X#endif /* ASCII */
  592. X
  593. X/* setjmp/longjmp args for DoKeys() mainjmp */
  594. X#define FIRSTCALL    0
  595. X#define ERROR        1
  596. X#define COMPLAIN    2    /* do the error without a getDOT */
  597. X#define QUIT        3    /* leave this level of recursion */
  598. X
  599. X#define QUIET        1    /* sure, why not? */
  600. X
  601. X#define YES        1
  602. X#define NO        0
  603. X#define TRUE        1
  604. X#define FALSE        0
  605. X#define ON        1
  606. X#define OFF        0
  607. X#define YES_NODIGIT    2
  608. X
  609. X#define INT_OKAY    0
  610. X#define INT_BAD        -1
  611. X
  612. extern char    *Mainbuf,
  613. X        *HomeDir,    /* home directory */
  614. X        key_strokes[],    /* strokes that make up current command */
  615. X        *Inputp;
  616. X
  617. extern int    HomeLen;    /* length of home directory */
  618. X
  619. extern char    NullStr[];
  620. X
  621. X#if defined(VMUNIX)||defined(MSDOS)
  622. extern char    genbuf[LBSIZE],
  623. X        linebuf[LBSIZE],
  624. X        iobuff[LBSIZE];
  625. X#else
  626. extern char    *genbuf,    /* scratch pad points at s_genbuf (see main()) */
  627. X        *linebuf,    /* points at s_linebuf */
  628. X        *iobuff;    /* for file reading ... points at s_iobuff */
  629. X#endif
  630. X
  631. extern int    InJoverc,
  632. X        Interactive;
  633. X
  634. X#define    READ    0
  635. X#define    WRITE    1
  636. extern int    errno;
  637. X
  638. extern jmp_buf    mainjmp;
  639. X
  640. X#ifdef IPROCS
  641. typedef struct process    Process;
  642. X#endif
  643. typedef struct window    Window;
  644. typedef struct position    Bufpos;
  645. typedef struct mark    Mark;
  646. typedef struct buffer    Buffer;
  647. typedef struct line    Line;
  648. typedef struct iobuf    IOBUF;
  649. typedef struct data_obj {
  650. X    int    Type;
  651. X    char    *Name;
  652. X} data_obj;    /* points to cmd, macro, or variable */
  653. X
  654. typedef data_obj    *keymap[NCHARS];
  655. X
  656. struct line {
  657. X    Line    *l_prev,        /* pointer to prev */
  658. X        *l_next;        /* pointer to next */
  659. X    disk_line    l_dline;    /* pointer to disk location */
  660. X};
  661. X
  662. X#ifdef IPROCS
  663. struct process {
  664. X    Process    *p_next;
  665. X#ifdef PIPEPROCS
  666. X    int    p_toproc,    /* read p_fromproc and write p_toproc */
  667. X        p_portpid,    /* pid of child (the portsrv) */
  668. X        p_pid;        /* pid of real child i.e. not portsrv */
  669. X#else
  670. X    int    p_fd,        /* file descriptor of pty? opened r/w */
  671. X        p_pid;        /* pid of child (the shell) */
  672. X#endif
  673. X    Buffer    *p_buffer;    /* add output to end of this buffer */
  674. X    char    *p_name;    /* ... */
  675. X    char    p_state,    /* State */
  676. X        p_howdied,    /* Killed? or Exited? */
  677. X        p_reason;    /* If signaled, p_reason is the signal; else
  678. X                   it is the the exit code */
  679. X    Mark    *p_mark;    /* where output left us */
  680. X    data_obj
  681. X        *p_cmd;        /* command to call when process dies */
  682. X};
  683. X#endif /* IPROCS */
  684. X
  685. struct window {
  686. X    Window    *w_prev,    /* circular list */
  687. X        *w_next;
  688. X    Buffer    *w_bufp;    /* buffer associated with this window */
  689. X    Line    *w_top,        /* top line */
  690. X        *w_line;    /* current line */
  691. X    int    w_char,
  692. X        w_height,    /* window height */
  693. X        w_topnum,    /* line number of the topline */
  694. X        w_dotcol,    /* UpdWindow sets this ... */
  695. X        w_dotline,    /* ... and this */
  696. X        w_flags,
  697. X#define    W_TOPGONE    01
  698. X#define    W_CURGONE    02    /* topline (curline) of window has been deleted
  699. X                   since the last time a redisplay was called */
  700. X#define W_VISSPACE    04
  701. X#define W_NUMLINES    010
  702. X        w_LRscroll;    /* amount of LeftRight scrolling in window */
  703. X#ifdef MAC
  704. X    int    w_topline;    /* row number of top line in window */
  705. X    char **w_control;    /* scroll bar for window */
  706. X#endif
  707. X};
  708. X
  709. extern Window    *fwind,        /* first window in list */
  710. X        *curwind;    /* current window */
  711. X
  712. struct position {
  713. X    Line    *p_line;
  714. X    int    p_char;
  715. X};
  716. X
  717. struct mark {
  718. X    Line    *m_line;
  719. X    int    m_char;
  720. X    Mark    *m_next;    /* list of marks */
  721. X#define M_FIXED        00
  722. X#define M_FLOATER    01
  723. X#define M_BIG_DELETE    02
  724. X    char    m_flags;    /* FLOATERing mark? */
  725. X};
  726. X
  727. struct buffer {
  728. X#ifdef MAC
  729. X    int Type;        /* kludge... to look like a data_obj */
  730. X    char *Name;        /* Name will not be used */
  731. X#endif    
  732. X    Buffer    *b_next;        /* next buffer in chain */
  733. X    char    *b_name,        /* buffer name */
  734. X        *b_fname;        /* file name associated with buffer */
  735. X    dev_t    b_dev;            /* device of file name. */
  736. X    ino_t    b_ino;            /* inode of file name */
  737. X    time_t    b_mtime;        /* last modify time ...
  738. X                       to detect two people writing
  739. X                       to the same file */
  740. X    Line    *b_first,        /* pointer to first line in list */
  741. X        *b_dot,            /* current line */
  742. X        *b_last;        /* last line in list */
  743. X    int    b_char;            /* current character in line */
  744. X
  745. X#define NMARKS    8            /* number of marks in the ring */
  746. X
  747. X    Mark    *b_markring[NMARKS],    /* new marks are pushed here */
  748. X        *b_marks;        /* all the marks for this buffer */
  749. X    char    b_themark,        /* current mark (in b_markring) */
  750. X        b_type,            /* file, scratch, process, iprocess */
  751. X        b_ntbf,            /* needs to be found when we
  752. X                       first select? */
  753. X        b_modified;        /* is the buffer modified? */
  754. X    int    b_major,        /* major mode */
  755. X        b_minor;        /* and minor mode */
  756. X    keymap    *b_keybinds;        /* local bindings (if any) */
  757. X#ifdef IPROCS
  758. X    Process    *b_process;        /* process we're attached to */
  759. X#endif
  760. X};
  761. X
  762. struct macro {
  763. X    int    Type;        /* in this case a macro */
  764. X    char    *Name;        /* name is always second ... */
  765. X    int    m_len,        /* length of macro so we can use ^@ */
  766. X        m_buflen,    /* memory allocated for it */
  767. X        m_flags;
  768. X    char    *m_body;    /* actual body of the macro */
  769. X    struct macro
  770. X        *m_nextm;
  771. X};
  772. X
  773. struct variable {
  774. X    int    Type;        /* in this case a variable */
  775. X    char    *Name;        /* name is always second */
  776. X    int    *v_value,
  777. X        v_flags;
  778. X};
  779. X
  780. struct cmd {
  781. X    int    Type;
  782. X    char    *Name;
  783. X#ifdef MAC
  784. X    void (*c_proc)();
  785. X#else
  786. X    int (*c_proc)();
  787. X#endif
  788. X#ifdef MAC
  789. X    char c_map;            /* prefix map for About Jove... */
  790. X    char c_key;            /* key binding for About Jove... */
  791. X#endif
  792. X};
  793. X
  794. extern keymap    mainmap,    /* various key maps */
  795. X        pref1map,
  796. X        pref2map,
  797. X        miscmap;
  798. X#ifdef MAC                    /* used in About Jove... */        
  799. X    #define F_MAINMAP '\001'
  800. X    #define F_PREF1MAP '\002'
  801. X    #define F_PREF2MAP '\003'
  802. X#endif
  803. X
  804. extern data_obj    *LastCmd;    /* last command invoked */
  805. X
  806. extern char    *ProcFmt;
  807. X
  808. extern struct cmd    commands[];
  809. extern struct macro    *macros;
  810. extern struct variable    variables[];
  811. X
  812. extern struct macro
  813. X    *macstack[],
  814. X    KeyMacro;
  815. X
  816. X#define FUNCTION    1
  817. X#define VARIABLE    2
  818. X#define MACRO        3
  819. X#ifdef MAC
  820. X#    define BUFFER        6    /* menus can point to buffers, too */
  821. X#    define STRING        7    /* a menu string or divider */
  822. X#endif
  823. X
  824. X#define TYPEMASK    07
  825. X#define MAJOR_MODE    010
  826. X#define MINOR_MODE    020
  827. X#define DefMajor(x)    (FUNCTION|MAJOR_MODE|(x << 8))
  828. X#define DefMinor(x)    (FUNCTION|MINOR_MODE|(x << 8))
  829. X
  830. extern Buffer    *world,        /* first buffer */
  831. X        *curbuf;    /* pointer into world for current buffer */
  832. X
  833. X#define curline    curbuf->b_dot
  834. X#define curchar curbuf->b_char
  835. X
  836. X#define NUMKILLS    10    /* number of kills saved in the kill ring */
  837. X
  838. X#ifdef MAC        /* when doing ~DIRTY, we need high bits set */
  839. X#    define DIRTY    (disk_line) 01    /* just needs updating for some reason */
  840. X#else
  841. X#    define DIRTY    01    /* just needs updating for some reason */
  842. X#endif
  843. X#define MODELINE    02    /* this is a modeline */
  844. X#define L_MOD        04    /* this line has been modified internally */
  845. X
  846. struct scrimage {
  847. X    int    s_offset,    /* offset to start printing at */
  848. X        s_flags,    /* various flags */
  849. X        s_id,        /* which buffer line */
  850. X        s_vln;        /* Visible Line Number */
  851. X    Line    *s_lp;        /* so we can turn off red bit */
  852. X    Window    *s_window;    /* window that contains this line */
  853. X};
  854. X
  855. extern struct scrimage
  856. X    *DesiredScreen,        /* what we want */
  857. X    *PhysScreen;        /* what we got */
  858. X
  859. X/* Variable flags (that can be set). */
  860. X#define V_BASE10    01    /* is integer in base 10 */
  861. X#define V_BASE8        02    /* is integer in base 8 */
  862. X#define V_BOOL        04    /* is a boolean */
  863. X#define V_STRING    010    /* is a string */
  864. X#define V_CHAR        020    /* is a character */
  865. X#define V_FILENAME    040    /* a file name (implies V_STRING) */
  866. X#define V_TYPEMASK    077    /* mask off the extra bits */
  867. X#define V_MODELINE    0100    /* update modeline */
  868. X#define V_CLRSCREEN    0200    /* clear and redraw screen */
  869. X#define V_TTY_RESET    0400    /* redo the tty modes */
  870. X
  871. X#ifdef MAC
  872. X#ifdef TXT_TO_C
  873. int        /* kludge, so setmaps will compile with variables */
  874. X#else
  875. extern int
  876. X#endif /* TXT_TO_C */
  877. X#else
  878. extern int
  879. X#endif    /* MAC */
  880. X
  881. X    OKXonXoff,        /* disable start/stop characters */
  882. X    MetaKey,        /* this terminal has a meta key */
  883. X    VisBell,        /* use visible bell (if possible) */
  884. X    WrapScan,        /* make searches wrap */
  885. X#ifndef MAC
  886. X    phystab,        /* terminal's tabstop settings */ 
  887. X#endif
  888. X    tabstop,        /* expand tabs to this number of spaces */
  889. X#ifdef BACKUPFILES
  890. X    BkupOnWrite,        /* make backup files when writing */
  891. X#endif
  892. X    RMargin,        /* right margin */
  893. X    LMargin,        /* left margin */
  894. X    ScrollStep,        /* how should we scroll */
  895. X#ifndef MAC
  896. X    WtOnMk,            /* write files on compile-it command */
  897. X#endif
  898. X    EndWNewline,        /* end files with a blank line */
  899. X    MarkThresh,        /* moves greater than MarkThresh will SetMark */
  900. X    PDelay,            /* paren flash delay in tenths of a second */
  901. X    CIndIncrmt,        /* how much each indentation level pushes
  902. X                   over in C mode */
  903. X    CreatMode,        /* default mode for creat'ing files */
  904. X    CaseIgnore,        /* case ignore search */
  905. X#ifdef ABBREV
  906. X    AutoCaseAbbrev,        /* automatically do case on abbreviations */
  907. X#endif
  908. X    MarksShouldFloat,    /* adjust marks on insertion/deletion */
  909. X    UseRE,            /* use regular expressions in search */
  910. X    SyncFreq,        /* how often to sync the file pointers */
  911. X    BriteMode,        /* make the mode line inverse? */
  912. X    OkayBadChars,        /* allow bad characters in files created
  913. X                   by JOVE */
  914. X    UpdFreq,        /* how often to update modeline */
  915. X    UseBuffers,        /* use buffers with Typeout() */
  916. X#ifdef BIFF
  917. X    BiffChk,        /* turn off/on biff with entering/exiting jove */
  918. X#endif
  919. X    MailInt,        /* mail check interval */
  920. X#ifdef ID_CHAR
  921. X    UseIC,            /* whether or not to use i/d char
  922. X                   processesing */
  923. X#endif
  924. X    SExitChar,        /* type this to stop i-search */
  925. X    AbortChar,        /* cancels command input */
  926. X    IntChar,        /* ttysets this to generate QUIT */
  927. X    DoEVexpand,        /* treat $foo as environment variable */
  928. X#ifdef F_COMPLETION
  929. X     DispBadFs,        /* display filenames with bad extensions? */
  930. X#endif    
  931. X#ifdef IBMPC
  932. X    Fgcolor,
  933. X    Bgcolor,
  934. X    Mdcolor,
  935. X#endif /* IBMPC */
  936. X#ifdef F_COMPLETION
  937. X    DispBadFs,        /* display filenames with bad extensions? */
  938. X#endif
  939. X    ScrollAll,        /* we current line scrolls, scroll whole window? */
  940. X#ifndef MAC
  941. X    EWSize;            /* size to make the error window */
  942. X#else    
  943. X    Macmode,    /* see mac.c */
  944. X    Keyonly,
  945. X    Bufchange,
  946. X    Modechange,
  947. X    Windchange,
  948. X    EventCmd;
  949. X#endif    /* MAC */
  950. X
  951. X#ifdef MAC
  952. X#    ifdef TXT_TO_C    /* kludge, for setmaps with variables */
  953. char
  954. X#    else
  955. extern char
  956. X#    endif /* TXT_TO_C */
  957. X#else
  958. extern char
  959. X#endif /* MAC */
  960. X
  961. X#ifndef MAC
  962. X    ErrFmtStr[256],        /* format string for parse errors */
  963. X#endif
  964. X#ifdef IPROCS
  965. X    proc_prompt[128],    /* process prompt */
  966. X#endif
  967. X#ifdef F_COMPLETION
  968. X    BadExtensions[128],    /* extensions (e.g., ".o" to ignore) */
  969. X#endif
  970. X#ifdef CMT_FMT
  971. X    CmtFmt[80],
  972. X#endif
  973. X    ModeFmt[120],        /* mode line format string */
  974. X#ifdef UNIX
  975. X    Mailbox[FILESIZE],        /* mailbox name */
  976. X#endif /* UNIX */
  977. X    TmpFilePath[FILESIZE],    /* directory/device to store tmp files */
  978. X    TagFile[FILESIZE],        /* default tag file */
  979. X    Shell[FILESIZE];        /* shell to use */
  980. X
  981. extern int
  982. X    TOabort,    /* flag set by Typeout() */
  983. X    io,        /* file descriptor for reading and writing files */
  984. X    errormsg,    /* last message was an error message
  985. X               so don't erase the error before it
  986. X               has been read */
  987. X    this_cmd,    /* ... */
  988. X    last_cmd,    /* last command ... to implement appending
  989. X               to kill buffer */
  990. X    RecDepth,    /* recursion depth */
  991. X    InputPending,    /* nonzero if there is input waiting to
  992. X               be processed */
  993. X     killptr,    /* index into killbuf */
  994. X    CanScroll,    /* can this terminal scroll? */
  995. X    Crashing,    /* we are in the middle of crashing */
  996. X    Asking,        /* are we on read a string from the terminal? */
  997. X    inIOread;    /* so we know whether we can do a redisplay. */
  998. X
  999. extern char    Minibuf[LBSIZE];
  1000. X
  1001. X#define curmark        (curbuf->b_markring[curbuf->b_themark])
  1002. X#define b_curmark(b)    (b->b_markring[b->b_themark])
  1003. X
  1004. extern Line    *killbuf[NUMKILLS];    /* array of pointers to killed stuff */
  1005. X
  1006. X#define MESG_SIZE 128
  1007. extern char    mesgbuf[MESG_SIZE];
  1008. X
  1009. struct screenline {
  1010. X    char    *s_line,
  1011. X        *s_length;
  1012. X};
  1013. X
  1014. extern int
  1015. X    LastKeyStruck;
  1016. X
  1017. extern int
  1018. X    InMacDefine,    /* are we defining a macro right now? */
  1019. X
  1020. X    CapLine,    /* cursor line and cursor column */
  1021. X    CapCol,
  1022. X
  1023. X    UpdModLine,    /* whether we want to update the mode line */
  1024. X    UpdMesg;    /* update the message line */
  1025. X
  1026. X#define CATCH \
  1027. X{\
  1028. X    jmp_buf    sav_jmp; \
  1029. X\
  1030. X    push_env(sav_jmp); \
  1031. X    if (setjmp(mainjmp) == 0) {
  1032. X
  1033. X#define ONERROR \
  1034. X    } else { \
  1035. X
  1036. X#define ENDCATCH \
  1037. X    } \
  1038. X    pop_env(sav_jmp); \
  1039. X}
  1040. X
  1041. X#include "externs.h"
  1042. END_OF_FILE
  1043. if test 16194 -ne `wc -c <'./jove.h'`; then
  1044.     echo shar: \"'./jove.h'\" unpacked with wrong size!
  1045. fi
  1046. # end of './jove.h'
  1047. fi
  1048. if test -f './util.c' -a "${1}" != "-c" ; then 
  1049.   echo shar: Will not clobber existing file \"'./util.c'\"
  1050. else
  1051. echo shar: Extracting \"'./util.c'\" \(16153 characters\)
  1052. sed "s/^X//" >'./util.c' <<'END_OF_FILE'
  1053. X/***************************************************************************
  1054. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  1055. X * is provided to you without charge, and with no warranty.  You may give  *
  1056. X * away copies of JOVE, including sources, provided that this notice is    *
  1057. X * included in all the files.                                              *
  1058. X ***************************************************************************/
  1059. X
  1060. X#include "jove.h"
  1061. X#include "ctype.h"
  1062. X#include "termcap.h"
  1063. X#include <signal.h>
  1064. X
  1065. X#ifdef MAC
  1066. X#    include "mac.h"
  1067. X#else
  1068. X#    include <varargs.h>
  1069. X#endif
  1070. X
  1071. X#ifdef MSDOS
  1072. X#include <time.h>
  1073. X#endif
  1074. X
  1075. struct cmd *
  1076. FindCmd(proc)
  1077. register void     (*proc)();
  1078. X{
  1079. X    register struct cmd    *cp;
  1080. X
  1081. X      for (cp = commands; cp->Name; cp++)
  1082. X        if (cp->c_proc == proc)
  1083. X            return cp;
  1084. X    return 0;
  1085. X}
  1086. X
  1087. int    Interactive;    /* True when we invoke with the command handler? */
  1088. data_obj    *LastCmd;
  1089. char    *ProcFmt = ": %f ";
  1090. X
  1091. void
  1092. ExecCmd(cp)
  1093. data_obj    *cp;
  1094. X{
  1095. X    LastCmd = cp;
  1096. X    if (cp->Type & MAJOR_MODE)
  1097. X        SetMajor((cp->Type >> 8));
  1098. X    else if (cp->Type & MINOR_MODE)
  1099. X        TogMinor((cp->Type >> 8));
  1100. X    else    switch (cp->Type&TYPEMASK) {
  1101. X        case MACRO:
  1102. X            do_macro((struct macro *) cp);
  1103. X            break;
  1104. X
  1105. X        case FUNCTION:
  1106. X            {
  1107. X                struct cmd    *cmd = (struct cmd *) cp;
  1108. X
  1109. X            if (cmd->c_proc)
  1110. X                (*cmd->c_proc)();
  1111. X            }
  1112. X    }
  1113. X}
  1114. X
  1115. Line *
  1116. lastline(lp)
  1117. register Line    *lp;
  1118. X{
  1119. X    register Line    *next;
  1120. X
  1121. X    while (next = lp->l_next)
  1122. X        lp = next;
  1123. X    return lp;
  1124. X}
  1125. X
  1126. private int    *slowp = 0;
  1127. X
  1128. char    key_strokes[100];
  1129. private char    *key_p = key_strokes;
  1130. X
  1131. void
  1132. init_strokes()
  1133. X{
  1134. X    key_strokes[0] = 0;
  1135. X    key_p = key_strokes;
  1136. X}
  1137. X
  1138. void
  1139. add_stroke(c)
  1140. X{
  1141. X    if (key_p + 5 > &key_strokes[(sizeof key_strokes) - 1])
  1142. X        key_p = key_strokes;
  1143. X    sprintf(key_p, "%p ", c);
  1144. X    key_p += strlen(key_p);
  1145. X}
  1146. X
  1147. void
  1148. slowpoke()
  1149. X{
  1150. X    if (slowp)
  1151. X        *slowp = YES;
  1152. X    f_mess(key_strokes);
  1153. X}
  1154. X
  1155. X#ifdef UNIX
  1156. X#ifdef BSD4_2
  1157. X#    define N_SEC    1    /* will be precisely 1 second on 4.2 */
  1158. X#else
  1159. X#    define N_SEC    2    /* but from 1 to 2 seconds otherwise */
  1160. X#endif
  1161. X#else /* MSDOS or MAC */
  1162. X#define N_SEC    1
  1163. int in_macro();
  1164. X#endif /* UNIX */
  1165. X
  1166. int
  1167. waitchar(slow)
  1168. int    *slow;
  1169. X{
  1170. X#ifdef UNIX
  1171. X#ifdef EUNICE
  1172. X    return getch();
  1173. X#endif
  1174. X    unsigned int    old_time;
  1175. X    int    c;
  1176. X    int    (*oldproc)();
  1177. X#else /* MSDOS or MAC */
  1178. X    long sw, time();
  1179. X#endif /* UNIX */
  1180. X
  1181. X    slowp = slow;
  1182. X    if (slow)
  1183. X        *slow = NO;
  1184. X#ifdef UNIX
  1185. X    oldproc = signal(SIGALRM, slowpoke);
  1186. X
  1187. X    if ((old_time = alarm((unsigned) N_SEC)) == 0)
  1188. X        old_time = UpdFreq;
  1189. X    c = getch();
  1190. X    (void) alarm(old_time);
  1191. X    (void) signal(SIGALRM, oldproc);
  1192. X
  1193. X    return c;
  1194. X#else /* MSDOS or MAC */
  1195. X#ifdef MAC
  1196. X    Keyonly = 1;
  1197. X    if(charp() || in_macro()) return getch();    /* to avoid flicker */
  1198. X#endif
  1199. X    time(&sw);
  1200. X    sw += N_SEC;
  1201. X    while(time(NULL) <= sw)
  1202. X        if (charp() || in_macro())
  1203. X            return getch();
  1204. X#ifdef MAC
  1205. X    menus_off();
  1206. X#endif
  1207. X    slowpoke();
  1208. X    return getch();
  1209. X#endif /* UNIX */
  1210. X}
  1211. X
  1212. X/* dir > 0 means forward; else means backward. */
  1213. X
  1214. char *
  1215. StrIndex(dir, buf, charpos, what)
  1216. char    *buf,
  1217. X    what;
  1218. X{
  1219. X    char    *cp = &buf[charpos],
  1220. X        c;
  1221. X
  1222. X    if (dir > 0) {
  1223. X        while (c = *cp++)
  1224. X            if (c == what)
  1225. X                return (cp - 1);
  1226. X    } else {
  1227. X        while (cp >= buf && (c = *cp--))
  1228. X            if (c == what)
  1229. X                return (cp + 1);
  1230. X    }
  1231. X    return 0;
  1232. X}
  1233. X
  1234. int
  1235. blnkp(buf)
  1236. register char    *buf;
  1237. X{
  1238. X    register char    c;
  1239. X
  1240. X    while ((c = *buf++) && (c == ' ' || c == '\t'))
  1241. X        ;
  1242. X    return c == 0;    /* It's zero if we got to the end of the Line */
  1243. X}
  1244. X
  1245. Line *
  1246. next_line(line, num)
  1247. register Line    *line;
  1248. register int    num;
  1249. X{
  1250. X    if (num < 0)
  1251. X        return prev_line(line, -num);
  1252. X    if (line)
  1253. X        while (--num >= 0 && line->l_next != 0)
  1254. X            line = line->l_next;
  1255. X    return line;
  1256. X}
  1257. X
  1258. Line *
  1259. prev_line(line, num)
  1260. register Line    *line;
  1261. register int    num;
  1262. X{
  1263. X    if (num < 0)
  1264. X        return next_line(line, -num);
  1265. X    if (line)
  1266. X        while (--num >= 0 && line->l_prev != 0)
  1267. X            line = line->l_prev;
  1268. X    return line;
  1269. X}
  1270. X
  1271. void
  1272. DotTo(line, col)
  1273. Line    *line;
  1274. X{
  1275. X    Bufpos    bp;
  1276. X
  1277. X    bp.p_line = line;
  1278. X    bp.p_char = col;
  1279. X    SetDot(&bp);
  1280. X}
  1281. X
  1282. X/* If bp->p_line is != current line, then save current line.  Then set dot
  1283. X   to bp->p_line, and if they weren't equal get that line into linebuf.  */
  1284. X
  1285. void
  1286. SetDot(bp)
  1287. register Bufpos    *bp;
  1288. X{
  1289. X    register int    notequal;
  1290. X
  1291. X    if (bp == 0)
  1292. X        return;
  1293. X
  1294. X    notequal = bp->p_line != curline;
  1295. X    if (notequal)
  1296. X        lsave();
  1297. X    if (bp->p_line)
  1298. X        curline = bp->p_line;
  1299. X    if (notequal)
  1300. X        getDOT();
  1301. X    curchar = bp->p_char;
  1302. X    if (curchar > length(curline))
  1303. X        curchar = length(curline);
  1304. X}
  1305. X
  1306. void
  1307. ToLast()
  1308. X{
  1309. X    SetLine(curbuf->b_last);
  1310. X    Eol();
  1311. X}
  1312. X
  1313. int    MarkThresh = 22;    /* average screen size ... */
  1314. static int    line_diff;
  1315. X
  1316. int
  1317. LineDist(nextp, endp)
  1318. register Line    *nextp,
  1319. X        *endp;
  1320. X{
  1321. X    (void) inorder(nextp, 0, endp, 0);
  1322. X    return line_diff;
  1323. X}
  1324. X
  1325. int
  1326. inorder(nextp, char1, endp, char2)
  1327. register Line    *nextp,
  1328. X        *endp;
  1329. X{
  1330. X    int    count = 0;
  1331. X    register Line    *prevp = nextp;
  1332. X
  1333. X    line_diff = 0;
  1334. X    if (nextp == endp)
  1335. X        return char1 < char2;
  1336. X
  1337. X    while (nextp || prevp) {
  1338. X        if (nextp == endp || prevp == endp)
  1339. X            break;
  1340. X        if (nextp)
  1341. X            nextp = nextp->l_next;
  1342. X        if (prevp)
  1343. X            prevp = prevp->l_prev;
  1344. X        count += 1;
  1345. X    }
  1346. X    if (nextp == 0 && prevp == 0)
  1347. X        return -1;
  1348. X    line_diff = count;
  1349. X
  1350. X    return nextp == endp;
  1351. X}
  1352. X
  1353. void
  1354. PushPntp(line)
  1355. register Line    *line;
  1356. X{
  1357. X    if (LineDist(curline, line) >= MarkThresh)
  1358. X        set_mark();
  1359. X}
  1360. X
  1361. void
  1362. ToFirst()
  1363. X{
  1364. X    SetLine(curbuf->b_first);
  1365. X}
  1366. X
  1367. int
  1368. length(line)
  1369. Line    *line;
  1370. X{
  1371. X    return strlen(lcontents(line));
  1372. X};
  1373. X
  1374. void
  1375. to_word(dir)
  1376. register int    dir;
  1377. X{
  1378. X    register char    c;
  1379. X
  1380. X    if (dir == FORWARD) {
  1381. X        while ((c = linebuf[curchar]) != 0 && !isword(c))
  1382. X            curchar += 1;
  1383. X        if (eolp()) {
  1384. X            if (curline->l_next == 0)
  1385. X                return;
  1386. X            SetLine(curline->l_next);
  1387. X            to_word(dir);
  1388. X            return;
  1389. X        }
  1390. X    } else {
  1391. X        while (!bolp() && (c = linebuf[curchar - 1], !isword(c)))
  1392. X            curchar -= 1;
  1393. X        if (bolp()) {
  1394. X            if (curline->l_prev == 0)
  1395. X                return;
  1396. X            SetLine(curline->l_prev);
  1397. X            Eol();
  1398. X            to_word(dir);
  1399. X        }
  1400. X    }
  1401. X}
  1402. X
  1403. X/* Are there any modified buffers?  Allp means include B_PROCESS
  1404. X   buffers in the check. */
  1405. X
  1406. int
  1407. ModBufs(allp)
  1408. X{
  1409. X    register Buffer    *b;
  1410. X
  1411. X    for (b = world; b != 0; b = b->b_next) {
  1412. X        if (b->b_type == B_SCRATCH)
  1413. X            continue;
  1414. X        if ((b->b_type == B_FILE || allp) && IsModified(b))
  1415. X            return 1;
  1416. X    }
  1417. X    return 0;
  1418. X}
  1419. X
  1420. char *
  1421. filename(b)
  1422. register Buffer    *b;
  1423. X{
  1424. X    return b->b_fname ? pr_name(b->b_fname, YES) : "[No file]";
  1425. X}
  1426. X
  1427. char *
  1428. itoa(num)
  1429. register int    num;
  1430. X{
  1431. X    static char    line[15];
  1432. X
  1433. X    sprintf(line, "%d", num);
  1434. X    return line;
  1435. X}
  1436. X
  1437. int
  1438. min(a, b)
  1439. register int    a,
  1440. X        b;
  1441. X{
  1442. X    return (a < b) ? a : b;
  1443. X}
  1444. X
  1445. int
  1446. max(a, b)
  1447. register int    a,
  1448. X        b;
  1449. X{
  1450. X    return (a > b) ? a : b;
  1451. X}
  1452. X
  1453. void
  1454. tiewind(w, bp)
  1455. register Window    *w;
  1456. register Buffer    *bp;
  1457. X{
  1458. X    int    not_tied = (w->w_bufp != bp);
  1459. X
  1460. X    UpdModLine = YES;    /* kludge ... but speeds things up considerably */
  1461. X    w->w_line = bp->b_dot;
  1462. X    w->w_char = bp->b_char;
  1463. X    w->w_bufp = bp;
  1464. X    if (not_tied)
  1465. X        CalcWind(w);    /* ah, this has been missing since the
  1466. X                   beginning of time! */
  1467. X}
  1468. X
  1469. extern int    Jr_Len;
  1470. X
  1471. char *
  1472. lcontents(line)
  1473. register Line    *line;
  1474. X{
  1475. X    if (line == curline)
  1476. X        return linebuf;
  1477. X    else
  1478. X        return lbptr(line);
  1479. X}
  1480. X
  1481. char *
  1482. ltobuf(line, buf)
  1483. Line    *line;
  1484. char    *buf;
  1485. X{
  1486. X    if (line == curline) {
  1487. X        if (buf != linebuf)
  1488. X            strcpy(buf, linebuf);
  1489. X        Jr_Len = strlen(linebuf);
  1490. X    } else
  1491. X        getline(line->l_dline, buf);
  1492. X    return buf;
  1493. X}
  1494. X
  1495. void
  1496. DOTsave(buf)
  1497. Bufpos *buf;
  1498. X{
  1499. X    buf->p_line = curline;
  1500. X    buf->p_char = curchar;
  1501. X}
  1502. X
  1503. X/* Return none-zero if we had to rearrange the order. */
  1504. X
  1505. int
  1506. fixorder(line1, char1, line2, char2)
  1507. register Line    **line1,
  1508. X        **line2;
  1509. register int    *char1,
  1510. X        *char2;
  1511. X{
  1512. X    Line    *tline;
  1513. X    int    tchar;
  1514. X
  1515. X    if (inorder(*line1, *char1, *line2, *char2))
  1516. X        return 0;
  1517. X
  1518. X    tline = *line1;
  1519. X    tchar = *char1;
  1520. X    *line1 = *line2;
  1521. X    *char1 = *char2;
  1522. X    *line2 = tline;
  1523. X    *char2 = tchar;
  1524. X
  1525. X    return 1;
  1526. X}
  1527. X
  1528. int
  1529. inlist(first, what)
  1530. register Line    *first,
  1531. X        *what;
  1532. X{
  1533. X    while (first) {
  1534. X        if (first == what)
  1535. X            return 1;
  1536. X        first = first->l_next;
  1537. X    }
  1538. X    return 0;
  1539. X}
  1540. X
  1541. X/* Make `buf' (un)modified and tell the redisplay code to update the modeline
  1542. X   if it will need to be changed. */
  1543. X
  1544. int    ModCount = 0;
  1545. X
  1546. void
  1547. modify()
  1548. X{
  1549. X    extern int    DOLsave;
  1550. X
  1551. X    if (!curbuf->b_modified) {
  1552. X        UpdModLine = YES;
  1553. X        curbuf->b_modified = YES;
  1554. X    }
  1555. X    DOLsave = YES;
  1556. X    if (!Asking)
  1557. X        ModCount += 1;
  1558. X}
  1559. X
  1560. void
  1561. unmodify()
  1562. X{
  1563. X    if (curbuf->b_modified) {
  1564. X        UpdModLine = YES;
  1565. X        curbuf->b_modified = NO;
  1566. X    }
  1567. X}
  1568. X
  1569. int
  1570. numcomp(s1, s2)
  1571. register char    *s1,
  1572. X        *s2;
  1573. X{
  1574. X    register int    count = 0;
  1575. X
  1576. X    while (*s1 != 0 && *s1++ == *s2++)
  1577. X        count += 1;
  1578. X    return count;
  1579. X}
  1580. X
  1581. char *
  1582. copystr(str)
  1583. char    *str;
  1584. X{
  1585. X    char    *val;
  1586. X
  1587. X    if (str == 0)
  1588. X        return 0;
  1589. X    val = emalloc(strlen(str) + 1);
  1590. X
  1591. X    strcpy(val, str);
  1592. X    return val;
  1593. X}
  1594. X
  1595. X#ifndef byte_copy
  1596. void
  1597. byte_copy(from, to, count)
  1598. register char    *from,
  1599. X        *to;
  1600. register int    count;
  1601. X{
  1602. X    while (--count >= 0)
  1603. X        *to++ = *from++;
  1604. X}
  1605. X#endif
  1606. X
  1607. void
  1608. len_error(flag)
  1609. X{
  1610. X    char    *mesg = "[line too long]";
  1611. X
  1612. X    if (flag == COMPLAIN) complain(mesg);
  1613. X        else error(mesg);
  1614. X}
  1615. X
  1616. X/* Insert num number of c's at offset atchar in a linebuf of LBSIZE */
  1617. X
  1618. void
  1619. ins_c(c, buf, atchar, num, max)
  1620. char    c, *buf;
  1621. X{
  1622. X    register char    *pp, *pp1;
  1623. X    register int    len;
  1624. X    int    numchars;    /* number of characters to copy forward */
  1625. X
  1626. X    if (num <= 0)
  1627. X        return;
  1628. X    len = atchar + strlen(&buf[atchar]);
  1629. X    if (len + num >= max)
  1630. X        len_error(COMPLAIN);
  1631. X    pp = &buf[len + 1];        /* + 1 so we can --pp (not pp--) */
  1632. X    pp1 = &buf[len + num + 1];
  1633. X    numchars = len - atchar;
  1634. X    while (numchars-- >= 0)
  1635. X        *--pp1 = *--pp;
  1636. X    pp = &buf[atchar];
  1637. X    while (--num >= 0)
  1638. X        *pp++ = c;
  1639. X}
  1640. X
  1641. int
  1642. TwoBlank()
  1643. X{
  1644. X    register Line    *next = curline->l_next;
  1645. X
  1646. X    return ((next != 0) &&
  1647. X        (*(lcontents(next)) == '\0') &&
  1648. X        (next->l_next != 0) &&
  1649. X        (*(lcontents(next->l_next)) == '\0'));
  1650. X}
  1651. X
  1652. void
  1653. linecopy(onto, atchar, from)
  1654. register char    *onto,
  1655. X        *from;
  1656. X{
  1657. X    register char    *endp = &onto[LBSIZE - 2];
  1658. X
  1659. X    onto += atchar;
  1660. X
  1661. X    while (*onto = *from++)
  1662. X        if (onto++ >= endp)
  1663. X            len_error(ERROR);
  1664. X}
  1665. X
  1666. char *
  1667. IOerr(err, file)
  1668. char    *err, *file;
  1669. X{
  1670. X    return sprint("Couldn't %s \"%s\".", err, file);
  1671. X}
  1672. X
  1673. X#ifdef UNIX
  1674. void
  1675. pclose(p)
  1676. int    *p;
  1677. X{
  1678. X    (void) close(p[0]);
  1679. X    (void) close(p[1]);
  1680. X}
  1681. X
  1682. void
  1683. dopipe(p)
  1684. int    p[];
  1685. X{
  1686. X    if (pipe(p) == -1)
  1687. X        complain("[Pipe failed]");
  1688. X}
  1689. X
  1690. X#endif /* UNIX */
  1691. X/* NOSTRICT */
  1692. X
  1693. char *
  1694. emalloc(size)
  1695. X{
  1696. X    register char    *ptr;
  1697. X
  1698. X    if (ptr = malloc((unsigned) size))
  1699. X        return ptr;
  1700. X    /* Try garbage collecting lines */
  1701. X    GCchunks();
  1702. X    if (ptr = malloc((unsigned) size))
  1703. X        return ptr;
  1704. X    /* Uh ... Oh screw it! */
  1705. X    error("[Out of memory] ");
  1706. X    /* NOTREACHED */
  1707. X}
  1708. X
  1709. X/* Return the basename of file F. */
  1710. X
  1711. char *
  1712. basename(f)
  1713. register char    *f;
  1714. X{
  1715. X    register char    *cp;
  1716. X
  1717. X    if (cp = rindex(f, '/'))
  1718. X        return cp + 1;
  1719. X    else
  1720. X#ifdef MSDOS
  1721. X        if (cp = rindex(f, '\\'))
  1722. X            return cp + 1;
  1723. X    else
  1724. X        if (cp = rindex(f, ':'))
  1725. X            return cp + 1;
  1726. X#endif /* MSDOS */
  1727. X        return f;
  1728. X}
  1729. X
  1730. void
  1731. push_env(savejmp)
  1732. jmp_buf    savejmp;
  1733. X{
  1734. X    byte_copy((char *) mainjmp, (char *) savejmp, sizeof (jmp_buf));
  1735. X}
  1736. X
  1737. void
  1738. pop_env(savejmp)
  1739. jmp_buf    savejmp;
  1740. X{
  1741. X    byte_copy((char *) savejmp, (char *) mainjmp, sizeof (jmp_buf));
  1742. X}
  1743. X
  1744. X#ifdef LOAD_AV
  1745. X# if defined(BSD4_2) && !defined(BSD2_10)
  1746. X#   if defined(PURDUE_EE) && (defined(vax) || defined(gould))
  1747. X
  1748. void
  1749. get_la(dp)
  1750. double *dp;
  1751. X{
  1752. X    *dp = (double) loadav(0) / 100.0;
  1753. X}
  1754. X
  1755. X#   else /* !PURDUE_EE || (!vax && !gould) */ 
  1756. X
  1757. X#ifdef sun
  1758. X#   include <sys/param.h>
  1759. X#endif
  1760. X#include <nlist.h>
  1761. X
  1762. static struct    nlist nl[] = {
  1763. X    { "_avenrun" },
  1764. X#define    X_AVENRUN    0
  1765. X    { "" }
  1766. X};
  1767. X
  1768. void
  1769. get_la(dp)
  1770. double    *dp;
  1771. X{
  1772. X#ifdef sun
  1773. X    long    avenrun[3];
  1774. X#else
  1775. X    double    avenrun[3];
  1776. X#endif
  1777. X    static int    kmem = 0;
  1778. X
  1779. X    if (kmem == -1) {
  1780. X        *dp = 4.0;    /* So shell commands will say "Chugging" */
  1781. X        return;
  1782. X    } else if (kmem == 0) {
  1783. X        if ((kmem = open("/dev/kmem", 0)) == -1) {
  1784. X            f_mess("Can't open kmem for load average.");
  1785. X            *dp = 4.0;
  1786. X            return;
  1787. X        }
  1788. X        nlist("/vmunix", nl);
  1789. X    }
  1790. X    lseek(kmem, (long) nl[X_AVENRUN].n_value, 0);
  1791. X    read(kmem, (char *) avenrun, sizeof(avenrun));
  1792. X#ifdef sun
  1793. X    *dp = (double) avenrun[0] / FSCALE;
  1794. X#else
  1795. X    *dp = avenrun[0];
  1796. X#endif
  1797. X}
  1798. X
  1799. X#    endif
  1800. X#  else /* !BSD4_2 || BSD2_10 */
  1801. X
  1802. void
  1803. get_la(dp)
  1804. double    *dp;
  1805. X{
  1806. X    short    avg[3];
  1807. X
  1808. X    gldav(avg);
  1809. X    *dp = (double) avg[0] / 256;
  1810. X}
  1811. X
  1812. X#  endif
  1813. X#endif /* LOAD_AV */
  1814. X
  1815. X/* get the time buf, designated by *timep, from FROM to TO. */
  1816. char *
  1817. get_time(timep, buf, from, to)
  1818. char    *buf;
  1819. time_t    *timep;
  1820. X{
  1821. X    time_t    now;
  1822. X    char    *cp;
  1823. X    extern char    *ctime();
  1824. X
  1825. X    if (timep != 0)
  1826. X        now = *timep;
  1827. X    else
  1828. X        (void) time(&now);
  1829. X    cp = ctime(&now) + from;
  1830. X#ifndef MSDOS
  1831. X    if (to == -1)
  1832. X#else /* MSDOS */
  1833. X    if ((to == -1) && (cp[strlen(cp)-1] == '\n'))
  1834. X#endif /* MSDOS */
  1835. X        cp[strlen(cp) - 1] = '\0';        /* Get rid of \n */
  1836. X    else
  1837. X        cp[to - from] = '\0';
  1838. X    if (buf) {
  1839. X        strcpy(buf, cp);
  1840. X        return buf;
  1841. X    } else
  1842. X        return cp;
  1843. X}
  1844. X
  1845. X#ifndef MSDOS
  1846. X#ifndef MAC
  1847. int
  1848. strlen(s)
  1849. register char    *s;
  1850. X{
  1851. X    register char    *base = s;
  1852. X
  1853. X    while (*s++)
  1854. X        ;
  1855. X    return (s - base) - 1;
  1856. X}
  1857. X
  1858. char *
  1859. index(s, c)
  1860. register char    *s;
  1861. register int    c;
  1862. X{
  1863. X    register int    c1;
  1864. X
  1865. X    if (c != 0)
  1866. X        while (c1 = *s++)
  1867. X            if (c == c1)
  1868. X                return s - 1;
  1869. X    return 0;
  1870. X}
  1871. X
  1872. int
  1873. strcmp(s1, s2)
  1874. register char    *s1,
  1875. X        *s2;
  1876. X{
  1877. X    if (!s1 || !s2)
  1878. X        return 1;    /* which is not zero ... */
  1879. X    while (*s1 == *s2++)
  1880. X        if (*s1++ == '\0')
  1881. X            return 0;
  1882. X    return (*s1 - *--s2);
  1883. X}
  1884. X
  1885. X#endif /* MAC */
  1886. X#endif /* MSDOS */
  1887. X
  1888. int
  1889. casecmp(s1, s2)
  1890. register char    *s1,
  1891. X        *s2;
  1892. X{
  1893. X    if (!s1 || !s2)
  1894. X        return 1;    /* which is not zero ... */
  1895. X    while (CharUpcase(*s1) == CharUpcase(*s2++))
  1896. X        if (*s1++ == '\0')
  1897. X            return 0;
  1898. X    return (*s1 - *--s2);
  1899. X}
  1900. X
  1901. int
  1902. casencmp(s1, s2, n)
  1903. register char    *s1,
  1904. X        *s2;
  1905. register int    n;
  1906. X{
  1907. X    if (!s1 || !s2)
  1908. X        return 1;    /* which is not zero ... */
  1909. X    while (--n >= 0  && (CharUpcase(*s1) == CharUpcase(*s2++)))
  1910. X        if (*s1++ == '\0')
  1911. X            return 0;
  1912. X    return ((n < 0) ? 0 : *s1 - *--s2);
  1913. X}
  1914. X
  1915. void
  1916. null_ncpy(to, from, n)
  1917. char    *to,
  1918. X    *from;
  1919. X{
  1920. X    (void) strncpy(to, from, n);
  1921. X    to[n] = '\0';
  1922. X}
  1923. X
  1924. X#ifndef MSDOS
  1925. X#ifndef MAC
  1926. void
  1927. strcpy(t, f)
  1928. register char    *t,
  1929. X        *f;
  1930. X{
  1931. X    while (*t++ = *f++)
  1932. X        ;
  1933. X}
  1934. X
  1935. X#endif /* MAC */
  1936. X#endif /* MSDOS */
  1937. X
  1938. X/* Tries to pause for delay/10 seconds OR until a character is typed
  1939. X   at the keyboard.  This works well on BSD4_2 and not so well on the
  1940. X   rest.  Returns 1 if it returned because of keyboard input, or 0
  1941. X   otherwise. */
  1942. X
  1943. X#ifdef MAC
  1944. void
  1945. SitFor(delay)
  1946. unsigned int    delay;
  1947. X{
  1948. X    long    start,
  1949. X        end;
  1950. X
  1951. X#define Ticks (long *) 0x16A    /* 1/60 sec */
  1952. X    Keyonly = 1;
  1953. X    redisplay();
  1954. X    start = *Ticks;
  1955. X
  1956. X    end = start + delay * 6;
  1957. X    do
  1958. X        if (InputPending = charp())
  1959. X            break;
  1960. X    while (*Ticks < end);
  1961. X}
  1962. X#else    /* not MAC */
  1963. X
  1964. void
  1965. SitFor(delay)
  1966. unsigned int    delay;
  1967. X{
  1968. X#ifndef MSDOS
  1969. X#if defined(BSD4_2) && !defined(BSD2_10)
  1970. X#include <sys/time.h>
  1971. X
  1972. X    struct timeval    timer;
  1973. X    long    readfds = 1;
  1974. X
  1975. X    timer.tv_sec = (delay / 10);
  1976. X    timer.tv_usec = (delay % 10) * 100000;
  1977. X
  1978. X    if (charp())
  1979. X        return;
  1980. X    /* gross that I had to snarf this from getch() */
  1981. X    if (!UpdMesg && !Asking) {    /* Don't erase if we are asking */
  1982. X        if (mesgbuf[0] && !errormsg)
  1983. X            message(NullStr);
  1984. X    }
  1985. X    redisplay();
  1986. X    select(1, &readfds, (long *)0, (long *)0, &timer);
  1987. X#else
  1988. X    static int cps[] = {
  1989. X        0,
  1990. X        5,
  1991. X        7,
  1992. X        11,
  1993. X        13,
  1994. X        15,
  1995. X        20,
  1996. X        30,
  1997. X        60,
  1998. X        120,
  1999. X        180,
  2000. X        240,
  2001. X        480,
  2002. X        960,
  2003. X        1920,
  2004. X        1920,
  2005. X    };
  2006. X    register int    nchars,
  2007. X            check_cnt;
  2008. X
  2009. X    if (charp())
  2010. X        return;
  2011. X    nchars = (delay * cps[ospeed]) / 10;
  2012. X    check_cnt = BufSize;
  2013. X    redisplay();
  2014. X    while ((--nchars > 0) && !InputPending) {
  2015. X        putchar(0);
  2016. X        if (--check_cnt == 0) {
  2017. X            check_cnt = BufSize;
  2018. X            InputPending = charp();
  2019. X        }
  2020. X    }
  2021. X#endif
  2022. X#else /* MSDOS */
  2023. X#include <bios.h>
  2024. X#include <dos.h>
  2025. X
  2026. X    long    start,
  2027. X        end;
  2028. X#ifndef IBMPC
  2029. X    struct dostime_t tc;
  2030. X#endif    
  2031. X
  2032. X    redisplay();
  2033. X#ifdef IBMPC
  2034. X    _bios_timeofday(_TIME_GETCLOCK, &start);
  2035. X#else
  2036. X    _dos_gettime(&tc);
  2037. X    start = (long)(tc.hour*60L*60L*10L)+(long)(tc.minute*60L*10L)+
  2038. X            (long)(tc.second*10)+(long)(tc.hsecond/10);
  2039. X#endif
  2040. X    end = (start + delay);
  2041. X    do  {
  2042. X        if (InputPending = charp())
  2043. X            break;
  2044. X#ifdef IBMPC
  2045. X        if (_bios_timeofday(_TIME_GETCLOCK, &start))
  2046. X            break;    /* after midnight */
  2047. X#else
  2048. X        start = (long)(tc.hour*60L*60L*10L)+(long)(tc.minute*60L*10L)+
  2049. X                (long)(tc.second*10)+(long)(tc.hsecond/10);
  2050. X#endif
  2051. X    }
  2052. X    while (start < end);
  2053. X#endif /* MSDOS */
  2054. X}
  2055. X#endif /* MAC */
  2056. X
  2057. int
  2058. sindex(pattern, string)
  2059. register char    *pattern,
  2060. X        *string;
  2061. X{
  2062. X    register int    len = strlen(pattern);
  2063. X
  2064. X    while (*string != '\0') {
  2065. X        if (*pattern == *string && strncmp(pattern, string, len) == 0)
  2066. X            return TRUE;
  2067. X        string += 1;
  2068. X    }
  2069. X    return FALSE;
  2070. X}
  2071. X
  2072. void
  2073. make_argv(argv, ap)
  2074. register char    *argv[];
  2075. va_list    ap;
  2076. X{
  2077. X    register char    *cp;
  2078. X    register int    i = 0;
  2079. X
  2080. X    argv[i++] = va_arg(ap, char *);
  2081. X    argv[i++] = basename(argv[0]);
  2082. X    while (cp = va_arg(ap, char *))
  2083. X        argv[i++] = cp;
  2084. X    argv[i] = 0;
  2085. X}
  2086. X
  2087. int
  2088. pnt_line()
  2089. X{
  2090. X    register Line    *lp = curbuf->b_first;
  2091. X    register int    i;
  2092. X
  2093. X    for (i = 0; lp != 0; i++, lp = lp->l_next)
  2094. X        if (lp == curline)
  2095. X            break;
  2096. X    return i + 1;
  2097. X}
  2098. END_OF_FILE
  2099. if test 16153 -ne `wc -c <'./util.c'`; then
  2100.     echo shar: \"'./util.c'\" unpacked with wrong size!
  2101. fi
  2102. # end of './util.c'
  2103. fi
  2104. echo shar: End of archive 8 \(of 21\).
  2105. cp /dev/null ark8isdone
  2106. MISSING=""
  2107. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  2108.     if test ! -f ark${I}isdone ; then
  2109.     MISSING="${MISSING} ${I}"
  2110.     fi
  2111. done
  2112. if test "${MISSING}" = "" ; then
  2113.     echo You have unpacked all 21 archives.
  2114.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2115. else
  2116.     echo You still need to unpack the following archives:
  2117.     echo "        " ${MISSING}
  2118. fi
  2119. ##  End of shell archive.
  2120. exit 0
  2121.